package com.aspire.wap.core.esi;

import java.util.Enumeration;
import java.util.Map;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.aspire.wap.core.common.StringUtil;

import sun.misc.BASE64Decoder;

import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;

/**
 * EsiObject是为了统一基于Esi架构的应用开发而设计的一个工具对象，在请求的过程中，
 * 完成对request和response对象的二次封装，简化开发流程。
 * 
 * <p>
 * 举例说明： <blockquote>
 * 
 * <pre>
 * new EsiObject(request, response)
 * </pre>
 * 
 * </blockquote>
 * <p>
 * 
 * @author wangxinning
 * @version 1.1, 05/12/2010
 * @since JDK1.5
 * @deprecated
 */

public class EsiObject {

	private static final Log log = LogFactory.getLog(EsiObject.class);

	private HttpServletRequest request;
	private HttpServletResponse response;
	private Map ParamMap = new HashMap();

	private Map SourceParamMap = new HashMap();

	private Map PostParamMap = new HashMap();
	private Map GetParamMap = new HashMap();

	private URL sourceUrl = null;

	public final static String Key_EsiTime = "X-dorton-ttl";// 缓存时间key
	public final static String Key_EsiUrl = "X-efrm-url";// 外部访问url key
	public final static String Key_UserID = "X-up-user-id";// 缓存时间key
	public final static String Param_ver = "asi_ver";// wap版本
	// public final static String Param_keys = "asi_keys";//缓存变量key
	public final static String Param_postarg = "postarg";// post传入参数
	public final static String Param_esitagID = "esitagID";

	/**
	 * 构造函数
	 * <p>
	 * 参数：request、response
	 * <p>
	 * 逻辑： 赋值给成员变量，填充数据到成员变量
	 */
	public EsiObject(HttpServletRequest request, HttpServletResponse response) {

		// 赋值给成员变量
		this.request = request;
		this.response = response;
		// 默认缓存时间设置为0
		this.setCacheTimes(0);

		log.debug("EsiObject---->request---->RequestURL=" + this.getCacheKey());

		// 给成员变量外部访问url对象赋值
		if (StringUtils.isNotEmpty(this.getSourceUrl())) {
			try {
				this.sourceUrl = new URL(this.getSourceUrl());
				log.debug("EsiObject---->request---->sourceUrl="
						+ this.getSourceUrl());
			} catch (Exception e) {
				log.error("ERROR--- EsiObject---->request---->sourceUrl=" + e);
			}
		}

		/*
		 * 参数存入parammap，可能会出现覆盖的情况，以覆盖后的数据为准
		 */
		// 首先将外部访问的所有参数存入参数map
		this.stringToMap(this.getSourceQuery(), this.ParamMap);
		this.stringToMap(this.getSourceQuery(), this.SourceParamMap);

		// 其次将post过来的参数存入
		this.addPostParamToMap();

		// 最后存入get参数
		this.addGetParamToMap();
	}

	/**
	 * 在response中设置缓存时间
	 * <p>
	 * 逻辑： 如果参数大于0，直接进行设置，单位是秒 如果小于等于0，直接设置为0
	 * 
	 * @param times
	 *            缓存时间，单位：秒.
	 */
	public void setCacheTimes(int times) {

		log.debug("EsiObject---->setCacheTimes=" + times + "s");
		if (response != null) {
			if (times > 0) {
				response.setHeader(Key_EsiTime, Integer.toString(times));
			} else {
				response.setHeader(Key_EsiTime, "0");
			}
		}
	}

	/**
	 * 获取请求需要返回的wap版本参数
	 * <p>
	 * 
	 * @return 版本编号，1：wap 1.X；2：wap 2.0
	 */
	public int getVersion() {
		int retInt = 1;

		if (NumberUtils.isNumber(request.getParameter(Param_ver))) {
			retInt = NumberUtils.toInt(request.getParameter(Param_ver));
		}

		return retInt;
	}

	/**
	 * 获取该页面在esi服务器的缓存key
	 */
	public String getCacheKey() {

		String cacheKey = this.request.getRequestURI();
		if (StringUtils.isNotEmpty(this.request.getQueryString())) {
			cacheKey += "?" + this.request.getQueryString();
		}

		return cacheKey;
	}

	/**
	 * 获取清缓存的命令，命令格式是 PURGE [key] ......
	 */
	public String getClearCacheCommand() {

		String key = this.getCacheKey();
		String appHost = this.request.getServerName();
		int appPort = this.request.getServerPort();

		String ppp = "";
		if (appPort != 80) {
			ppp = ":" + appPort;
		}

		return "PURGE " + key + " HTTP/1.1 \r\nHOST: " + appHost + ppp
				+ "\r\n\r\n";
	}

	/**
	 * 打印日志用
	 * <p>
	 * 请求参数的键值对显示
	 */
	public String requestToString() {
		return this.request.getParameterMap().toString();
	}

	/**
	 * 打印日志用
	 * <p>
	 * 请求头的键值对显示
	 */
	public String requestHeadToString() {

		String str = "";

		Enumeration enu = this.request.getHeaderNames();

		while (enu.hasMoreElements()) {
			String key = enu.nextElement().toString();

			str += key + "=" + this.request.getHeader(key) + "\n";
		}

		return str;
	}

	/**
	 * 只在构造函数中调用
	 * <p>
	 * 将get的参数存入参数map
	 */
	private void addGetParamToMap() {

		Enumeration enu = this.request.getParameterNames();

		while (enu.hasMoreElements()) {
			String key = enu.nextElement().toString();
			String value = this.request.getParameter(key);

			if (StringUtils.isNotEmpty(key) && StringUtils.isNotEmpty(value)
					&& !key.equals(Param_postarg)) {

				this.ParamMap.put(key, StringUtil.utf8Togb2312(value));
				this.GetParamMap.put(key, StringUtil.utf8Togb2312(value));

				log.debug("EsiObject---->addGetParamToMap---->" + key + "="
						+ StringUtil.utf8Togb2312(value));
			}
		}
	}

	/**
	 * 将esi外部的post请求参数存入map
	 */
	private void addPostParamToMap() {
		String postarg = request.getParameter(Param_postarg);

		if (StringUtils.isNotEmpty(postarg)) {

			BASE64Decoder decoder = new BASE64Decoder();

			try {
				byte[] bbb = decoder.decodeBuffer(postarg);
				postarg = new String(bbb);

				log.debug("EsiObject---->Param_postarg---->" + postarg);

				this.stringToMap(postarg, this.ParamMap);
				this.stringToMap(postarg, this.PostParamMap);

			} catch (Exception e) {

				log.error("ERROR--- EsiObject---->addPostParamToMap:" + e);
			}
		}
	}

	/**
	 * 获取esi外部访问url
	 */
	public String getSourceUrl() {
		String str = this.request.getHeader(Key_EsiUrl);

		if (StringUtils.isNotEmpty(str)) {
			return str;
		} else {
			return "";
		}
	}

	/**
	 * 获取esi外部访问Host
	 */
	public String getSourceHost() {
		if (this.sourceUrl != null) {
			return this.sourceUrl.getHost();
		} else {
			return "";
		}

	}

	/**
	 * 获取esi外部访问Port
	 */
	public int getSourcePort() {
		if (this.sourceUrl != null) {
			return this.sourceUrl.getPort();
		} else {
			return 0;
		}
	}

	/**
	 * 获取esi外部访问Path
	 */
	public String getSourcePath() {
		if (this.sourceUrl != null) {
			return this.sourceUrl.getPath();
		} else {
			return "";
		}

	}

	/**
	 * 获取esi外部访问Protocol
	 */
	public String getSourceProtocol() {
		if (this.sourceUrl != null) {
			return this.sourceUrl.getProtocol();
		} else {
			return "";
		}

	}

	/**
	 * 获取esi外部访问Query
	 */
	public String getSourceQuery() {
		if (this.sourceUrl != null) {
			return this.sourceUrl.getQuery();
		} else {
			return "";
		}

	}

	/**
	 * 获取所有参数Map
	 */
	public Map getParamMap() {
		return this.ParamMap;
	}

	/**
	 * 获取外部链接中的参数Map
	 */
	public Map getSourceParamMap() {
		return this.SourceParamMap;
	}

	/**
	 * 获取POST参数Map
	 */
	public Map getPostParamMap() {
		return this.PostParamMap;
	}

	/**
	 * 获取GET参数Map
	 */
	public Map getGetParamMap() {
		return this.GetParamMap;
	}

	public String getParameter(String key) {
		if (this.ParamMap != null) {
			return (String) this.ParamMap.get(key);
		} else {
			return null;
		}
	}

	/**
	 * 解析字符串，将其中的参数存入参数map的通用方法
	 */
	private void stringToMap(String str, Map map) {
		if (StringUtils.isNotEmpty(str)) {

			String[] subStr = StringUtils.split(str, "&");

			if (subStr != null && subStr.length > 0) {
				for (int i = 0; i < subStr.length; i++) {
					String tempStr = subStr[i];

					if (tempStr.indexOf("=") != -1) {

						String key = tempStr.substring(0, tempStr.indexOf("="));
						String value = tempStr
								.substring(tempStr.indexOf("=") + 1);

						try {
							value = URLDecoder.decode(value, "utf-8");
							map.put(key, value);
							log.debug("EsiObject---->stringToMap---->" + key
									+ "=" + value);
						} catch (Exception e) {
							log
									.error("ERROR--- EsiObject---->stringToMap:"
											+ e);
						}
					}
				}
			}
		}
	}

	/**
	 * 获取内部使用的UserID
	 */
	public String getUserID() {
		String str = this.request.getHeader(Key_UserID);

		if (StringUtils.isNotEmpty(str)) {
			return StringUtils.trim(str);
		} else {
			str = this.request.getParameter(Key_UserID);
			if (StringUtils.isNotEmpty(str)) {
				return StringUtils.trim(str);
			}
		}

		return "";

	}

	public static String chineseFilter(String oriStr) {
		String filtedStr = oriStr;

		String titleRegex = "(\\?{4})";

		Pattern pattern = Pattern.compile(titleRegex);
		Matcher matcher = pattern.matcher(filtedStr);

		if (matcher.find()) {
			try {
				filtedStr = new String(oriStr.getBytes("UTF-8"), "iso-8859-1");
			} catch (UnsupportedEncodingException e) {
				// logger.warn("[标签名=CommonUtil,功能=中文乱码过滤,]");
			}
		}
		// end of 2008-04-22
		return filtedStr;
	}

	public static void main(String[] args) throws Exception {
		URL aURL = new URL("http://java.sun.com:80/docs/books/tutorial"
				+ "/index.html?name=networking&aaa=ddd&ccc=ddd#DOWNLOADING");

		aURL = new URL("http://3g.i139.cn/pams2/e.do?j=l&p=4&c=11077");

		System.out.println("protocol = " + aURL.getProtocol());

		System.out.println("authority = " + aURL.getAuthority());
		System.out.println("host = " + aURL.getHost());

		System.out.println("port = " + aURL.getPort());

		System.out.println("path = " + aURL.getPath());

		System.out.println("query = " + aURL.getQuery());

		System.out.println("filename = " + aURL.getFile());

		System.out.println("ref = " + aURL.getRef());
	}

}
